#include "factory.h"
// 得到命令的key值
int cmd_type_func(char *cmd)
{
    if(cmd[0]=='p')
    {
        if(cmd[1]=='u')
            return PUTS;
        else
            return PWD;
    }
    else if(cmd[0]=='g')
        return GETS;
    else if(cmd[0]=='c')
        return CD;
    else if(cmd[0]=='l')
        return LS;
    else if(cmd[0]=='r')
        return REMOVE;
    else if(cmd[0]=='l')
        return LOGIN;
    else if(cmd[0]=='r')
        return REGISTER;
    else if(cmd[0]=='q')
        return QUIT;
    else
        return -1;
}

//打印登录界面
void print_login()
{
    printf("-----------------------------------------------------------------------\n");
    printf("-------------------------WELCOME TO KK_NET.DISK------------------------\n");
    printf("------请按照提示尽快完成登录界面的操作,以免阻塞其他用户,感谢您的配合!-------\n");
    printf("-----------------------------------------------------------------------\n");
}

//token验证
int client_token(int sfd,train_state_t* ct,char *token)
{
    int ret,data_len=0;
    ct->cmd_type=TOKEN;
    ct->data_len=strlen(token);//将token长度装在火车头
    strcpy(ct->buf,token);//将token内容装在火车车厢
    ret=send_n(sfd,&ct->data_len,sizeof(int));//发送token长度，以及TOKEN命令
    SELFFUNC_ERR_CHECK(ret,"send_n");
    ret=send_n(sfd,&ct,4+ct->data_len);//发送token内容
    SELFFUNC_ERR_CHECK(ret,"send_n");
    ret=recv_n(sfd,&data_len,4);
    if(0==data_len)
    {
        return -1;
    }
    else{
        return 0;
    }
}

//用户输入账号密码，并传给服务器端进行密码验证,成功之后在进行命令的传输
int client_login(int sfd,char *token,usraddr usr)
{
    char *passwd;//明文密码
    int ret,cor;;
    char *crpwd;
    char salt[512]={0};
    int data_len;
    char buf[1000]={0};
    printf("usrname :");
    scanf("%s",usr.usrA);//用户输入用户名
    passwd=getpass("Input a password(不会明文显示):");//用户输入一个明文密码
    printf("The passwd is:%s\n",passwd);
    usr.data_len=sizeof(usr.usrA);
    ret=send_n(sfd,&usr.data_len,sizeof(int));//发送用户名长度
    SELFFUNC_ERR_CHECK(ret,"send_n");
    ret=send_n(sfd,&usr.usrA,4+usr.data_len);//发送用户名内容
    SELFFUNC_ERR_CHECK(ret,"send_n");
    int salt_len=sizeof(salt);
    ret=recv_n(sfd,&salt_len,sizeof(int));//接收salt长度
    SELFFUNC_ERR_CHECK(ret,"recv_n");
    if(salt_len==0)//如果是空火车
    {
        printf("Usr name error!\n");
        return -1;
    }
    ret=recv_n(sfd,salt,4+salt_len);//接收salt内容
    SELFFUNC_ERR_CHECK(ret,"recv_n");
    strcpy(token,salt);//存token
    crpwd=crypt(passwd,salt);//将用户的密码与salt加密得到一个与密码文件中密码进行对比的加密字符串
    sprintf(usr.pwd,"%s",crpwd);
    usr.data_len=sizeof(usr.pwd);
    ret=send_n(sfd,&usr.data_len,sizeof(int));//发送加密字符串长度
    SELFFUNC_ERR_CHECK(ret,"send_n");
    ret=send_n(sfd,usr.pwd,4+usr.data_len);
    SELFFUNC_ERR_CHECK(ret,"send_n");//发送加密字符串内容
    //客户端接收服务器的密码确认信息,密码正确接到token，错误则收到空火车
    ret=recv_n(sfd,&data_len,sizeof(int));
    SELFFUNC_ERR_CHECK(ret,"recv_n");
    if(0==data_len)
    {
        printf("wrong user or passwd!\n");
        return -1;
    }
    else{
        printf("welcome %s!\n",usr.usrA);
        ret=recv_n(sfd,&buf,data_len);
        strcpy(token,buf);//存token
        command_options();
        return 0;
    }
}

//用户输入账号密码，并传给服务器端进行注册
int client_register(int sfd,char *token,usraddr usr)
{
    char buf[128]={0};
    char *passwd;//明文密码
    int ret;
    printf("usrname :");
    scanf("%s",usr.usrA);//用户输入用户名
    passwd=getpass("Input a password(不会明文显示):");//用户输入一个明文密码
    printf("The passwd is:%s\n",passwd);
    usr.data_len=sizeof(usr.usrA);
    ret=send_n(sfd,&usr.data_len,sizeof(int));//发送用户名长度
    SELFFUNC_ERR_CHECK(ret,"send_n");
    ret=send_n(sfd,&usr.usrA,4+usr.data_len);//发送用户名内容
    SELFFUNC_ERR_CHECK(ret,"send_n");
    usr.data_len=sizeof(passwd);
    ret=send_n(sfd,&usr.data_len,sizeof(int));//发送密码长度
    SELFFUNC_ERR_CHECK(ret,"send_n");
    ret=send_n(sfd,&passwd,4+usr.data_len);//发送密码内容
    SELFFUNC_ERR_CHECK(ret,"send_n");
    int len=sizeof(buf);
    ret=recv_n(sfd,&len,sizeof(int));//接收注册结果或token的长度
    SELFFUNC_ERR_CHECK(ret,"recv_n");
    if(len==0)//注册失败
    {
        printf("username exist!\n");
        return -1;
    }
    else{
        ret=recv_n(sfd,buf,len);//接收注册结果或token的内容
        SELFFUNC_ERR_CHECK(ret,"recv_n");
        strcpy(token,buf);//存下token
        printf("welcome %s!\n",usr.usrA);
        command_options();
        return 0;
    }
}
//检查login锁,若为0则可登录,为1则堵塞
int check_login_mutex1(int mutex,char* mutex_buf,char* one_buf,char* zero_buf)
{
    int ret;
    ret=read(mutex,mutex_buf,sizeof(mutex_buf));
    ERROR_CHECK(ret,-1,"read");
    if(!strcmp(mutex_buf,"0"))//锁文件里为0，代表可以登录
    {
        //加login锁
        lseek(mutex,0,SEEK_SET);
        ret=write(mutex,one_buf,1);
        ERROR_CHECK(ret,-1,"write1");
    }
    else if(!strcmp(mutex_buf,"1"))
    {
        printf("\n");
        printf("-----------------------------------------------------------------------\n");
        printf("-------Someone else is preparing to login/regist/quit,please wait------\n");
        printf("-----------------------------------------------------------------------\n");
        printf("\n");
        while(1)//检测到锁打开，就解锁
        {
            lseek(mutex,0,SEEK_SET);
            read(mutex,mutex_buf,sizeof(mutex_buf));
            if(!strcmp(mutex_buf,"0"))//锁文件里为0，代表可以登录
            {
                //加锁
                lseek(mutex,0,SEEK_SET);
                ret=write(mutex,one_buf,1);
                ERROR_CHECK(ret,-1,"write0");
                break;//退出
            }
        }
    }
}